﻿using System;
using System.Linq;
using System.Reflection;
using HtmlAgilityPack;

namespace HtmlShaper
{
	class HtmlShaper
	{
		public static T Shape<T>(HtmlNode documentNode) where T : ShaperNode, new()
		{
			return (T) Shape(typeof (T), documentNode);
		}

		public static ShaperNode Shape(Type type, HtmlNode documentNode)
		{
			var result = (ShaperNode)Activator.CreateInstance(type);
			result.HtmlNode = documentNode;

			var nodes = documentNode.ChildNodes.Where(n => n.NodeType == HtmlNodeType.Element).GetEnumerator();

			FieldInfo[] fields = type.GetFields();
			foreach (var field in fields)
			{
				var byClass = (ClassAttribute[])field.GetCustomAttributes(typeof(ClassAttribute), false);
				var byTags = (TagAttribute[])field.GetCustomAttributes(typeof (TagAttribute), false);
				var byText = (TextAttribute[])field.GetCustomAttributes(typeof(TextAttribute), false);

//				if (field.FieldType.IsArray)
//					field.
				while (nodes.MoveNext())
				{
					HtmlNode node = nodes.Current;
					if (byTags.Any() && !byTags.Any(t => t.Tag.ToString().Equals(node.Name, StringComparison.OrdinalIgnoreCase)))
						continue;
					if (byClass.Any())
					{
						var attr = node.Attributes.FirstOrDefault(a => a.Name == "class");
						if (attr == null || !byClass.Any(t => t.ClassName.ToString().Equals(attr.Value, StringComparison.OrdinalIgnoreCase)))
							continue;
					}
					if (byText.Any() && !byText.Any(t => t.Text.ToString().Equals(node.InnerText, StringComparison.OrdinalIgnoreCase)))
						continue;

					var fieldType = field.FieldType;
					object fieldValue = fieldType == typeof (string) ? (object) node.InnerText : Shape(fieldType, node);
					field.SetValue(result, fieldValue);
					break;
				}
			}

			return result;
		}
	}
}